﻿using Data.Odbc.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Data.Odbc
{
    public class Repository : IRepository, IDisposable
    {
        private readonly Semaphore _mSemaphore;//信号量;
        private string connStr = string.Empty;
        private int timeout = 30;
        private Pool m_pool = new Pool(10);
        private int m_poolCount = 0;
        private int m_runtimePool = 0;

        public int GetRunTimePoolCount { get { return this.m_runtimePool; } }


        public Repository(int poolCount, string connStr, int timeout = 30)
        {
            m_poolCount = poolCount;
            m_pool = new Pool(poolCount);
            for (int i = 0; i < poolCount; i++)
            {
                m_pool.Push(new Args.PoolArgs()
                {
                    handle = new Core.Helper(connStr, timeout)
                });
            }
        }

        private Args.PoolArgs getSession()
        {
            _mSemaphore.WaitOne();
            System.Threading.Interlocked.Increment(ref m_runtimePool);
            return this.m_pool.Pop();
        }

        /// <summary>
        /// 执行SQL
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns>int:受影响行数</returns>
        public int Exec(string sql)
        {
            var session = getSession();
            return (session.handle as Helper).Exec(sql);
        }


        public IQueryable Query(string sql)
        {
            var session = getSession();
            return (session.handle as Helper).Query(sql);
        }

        public void Close(Args.PoolArgs session)
        {
            (session.handle as Helper).Close();
            m_pool.Push(session);
            System.Threading.Interlocked.Decrement(ref m_runtimePool);
            _mSemaphore.Release();
        }
        /// <summary>
        /// 事务处理
        /// </summary>
        /// <param name="sqls">sql语句</param>
        /// <returns>boolen</returns>
        public bool Trans(IList<string> sqls, IList<System.Data.Odbc.OdbcParameter> _params)
        {
            //TODO 事务
            throw new NotImplementedException();
        }

        public virtual void Dispose(bool disposing)
        {
            m_pool.Dispose();
            GC.SuppressFinalize(this);
        }
        public void Dispose()
        {
            Dispose(true);
        }
    }


    /// <summary>
    /// 使用示范
    /// </summary>
    public static class DB
    {
        public static IRepository Context;
        static DB()
        {
            int poolCount = 100;
            string connStr = string.Empty;
            int timeOut = 0;
            Context = new Repository(poolCount, connStr, timeOut);
        }
    }
}
